package dm.ast.model.gen.factory;

import dm.ast.DmSelect;
import dm.sql.comp.ASTComplex;
import dm.sql.comp.SQLComplexity;
import dm.sql.comp.SQLComplexity.*;
import test.utility.Randomly;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * @author weihuixin
 * @date 2024/2/28
 * @Description SELECT的复杂度模板设置
 */
public class SelectModelFactory extends BaseModelFactory {
    static int COUNT_EXTREME = 13;

    //根据sql复杂度,得到AST的宽度、深度
    public static ASTComplex SQLCompToASTComp(SQLComplexity comp) {
        ASTComplex complexity = new ASTComplex();
        int wid_t = 0;
        int dep_t = 0;

        switch (comp) {
            case Cpx0:
                dep_t = 1;
                if (FactoryConstant.MIN_WIDT_COMP < SQLComplexity.WID_LEVEL0) {
                    wid_t = Randomly.getInteger(FactoryConstant.MIN_WIDT_COMP, SQLComplexity.WID_LEVEL0);
                } else {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0, FactoryConstant.MAX_WIDTH);
                }
                break;
            case Cpx1:
                dep_t = Randomly.fromOptions(1, 2);
                if (dep_t == 1) {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0, FactoryConstant.MAX_WIDTH);
                } else {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0,
                            SQLComplexity.WID_LEVEL1 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL1 : FactoryConstant.MAX_WIDTH);
                }
                break;
            case Cpx2:
                dep_t = Randomly.fromOptions(2, 3);
                if (dep_t == 2) {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL1 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL1 : SQLComplexity.WID_LEVEL0,
                            FactoryConstant.MAX_WIDTH);
                } else {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0,
                            SQLComplexity.WID_LEVEL2 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL2 : FactoryConstant.MAX_WIDTH);
                }
                break;
            case Cpx3:
                dep_t = Randomly.fromOptions(3, 4);
                if (dep_t == 3) {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL2 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL2 : SQLComplexity.WID_LEVEL0,
                            FactoryConstant.MAX_WIDTH);
                } else {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0,
                            SQLComplexity.WID_LEVEL3 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL3 : FactoryConstant.MAX_WIDTH);
                }
                break;
            case Cpx4:
                dep_t = Randomly.fromOptions(4, 5);
                if (dep_t == 4) {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL3 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL3 : SQLComplexity.WID_LEVEL0,
                            FactoryConstant.MAX_WIDTH);
                } else {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0,
                            SQLComplexity.WID_LEVEL4 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL4 : FactoryConstant.MAX_WIDTH);
                }
                break;
            case Cpx5:
                dep_t = Randomly.fromOptions(5, 6);
                if (dep_t == 5) {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL4 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL4 : SQLComplexity.WID_LEVEL0,
                            FactoryConstant.MAX_WIDTH);
                } else {
                    wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0,
                            SQLComplexity.WID_LEVEL5 < FactoryConstant.MAX_WIDTH ? SQLComplexity.WID_LEVEL5 : FactoryConstant.MAX_WIDTH);
                }
                break;
            default:
                if (FactoryConstant.MAX_WIDTH < 6) {
                    dep_t = 6;
                } else {
                    dep_t = Randomly.getInteger(6, FactoryConstant.MAX_WIDTH);
                }
                wid_t = Randomly.getInteger(SQLComplexity.WID_LEVEL0, FactoryConstant.MAX_WIDTH);
                break;
        }
        complexity.wid_t = wid_t;
        complexity.dep_t = dep_t;
        return complexity;
    }

    //根据sql复杂度量级别,得到AST的宽度、深度
    public static ASTComplex levelToASTComp(ComplexLevel level) {
        SQLComplexity comp = SQLComplexity.Cpx4;
        switch (level) {
            case EASY:
                comp = SQLComplexity.Cpx0;
                break;
            case MEDIUM:
                comp = Randomly.fromOptions(SQLComplexity.Cpx1, SQLComplexity.Cpx2);
                break;
            case HARD:
                comp = Randomly.fromOptions(SQLComplexity.Cpx3, SQLComplexity.Cpx4);
                break;
            default://ExtraHard
                comp = Randomly.fromOptions(SQLComplexity.Cpx5, SQLComplexity.Cpx6);
                break;
        }
        return SQLCompToASTComp(comp);
    }

    //根据宽度、深度返回SELECT语句各部分的复杂度分配模型
    public static List<ComplexityModel> selectModels(int wid_t, int dep_t, boolean withStatement, BaseModelFactory baseModelF) {
        List<ComplexityModel> models = new ArrayList<ComplexityModel>();
        //创建模型的时候,宽度wid_t需要减少1,代表select关键字
        //1.极端分配, modelExtreme, 如果有没有自查询，深度比较简单，这个方法返回13个ComplexityModel，如果有子查询，这深度可能在where上等等情况，返回的模型会更多
        models.addAll(modelExtreme(wid_t - 1, dep_t, withStatement, baseModelF));
        //2.深度平均分配
        // 需要多生成几个深度平均分配的模板以供后续使用 同样也是生成13个通过深度平均分配得到的模型ComplexityModel
        for (int i = 0; i < FactoryConstant.COUNT_AVERAGE; i++) {
            models.add(modelAverage(wid_t - 1, dep_t, withStatement, baseModelF));
        }
        //其余分配策略有待实现
        // TODO
        return models;
    }

    //根据AST的复杂度返回SELECT语句各部分的复杂度分配模型
    public static List<ComplexityModel> selectModels(ASTComplex comp, boolean withStatement, BaseModelFactory baseModelF) {
        return selectModels(comp.wid_t, comp.dep_t, withStatement, baseModelF);
    }

    //根据sq1的复杂度返回回SELECT语句各部分的复杂度分配模型
    public static List<ComplexityModel> selectModels(SQLComplexity comp, boolean withStatement, BaseModelFactory baseModelF) {
        ASTComplex complexity = SQLCompToASTComp(comp);
        return selectModels(complexity, withStatement, baseModelF);
    }

    //根据sq1复杂度量级别近回SELECT语包各部分的复杂度分配摸型
    public static List<ComplexityModel> selectModels(ComplexLevel comp, boolean withStatement, BaseModelFactory baseModelF) {
        ASTComplex complexity = levelToASTComp(comp);  //通过astLevel得到了树的宽度和深度，如果没有给定astLevel默认难度是cpx4
        return selectModels(complexity, withStatement, baseModelF);
    }

    //极端分配
    public static List<ComplexityModel> modelExtreme(int wid_t, int dep_t, boolean withStatement, BaseModelFactory
            baseModelF) {
        List<ComplexityModel> extreme = new ArrayList<ComplexityModel>();
        int i = 0;
        if (wid_t > 5) {
            //1.主要在FROM子句上
            for (i = 0; i < COUNT_EXTREME; i++) {
                //生成COUNT_EXTREME 13个ComplexityModel 每一个13个ComplexityModel都包含model.comp[11]的ASTComplex
                extreme.add(extremeFrom(wid_t, dep_t, withStatement, baseModelF));
            }
            boolean[] flags = BaseModelFactory.getRandExpTypes();
            if (flags[BaseModelFactory.INDEX_SUBSELECT]) { //如果有子查询,那么考虑深度可能在查询列、where子句上。
                // 2.都在查询列上,此时可以省略From、where、group等子句。
                extreme.add(extremeSelElements(wid_t, dep_t, withStatement, baseModelF));
                //3.在where子包上
                for (i = 0; i < COUNT_EXTREME; i++) {
                    extreme.add(extremeWhere(wid_t, dep_t, withStatement, baseModelF));
                }
            }
        }
        //4.TODO
        return extreme;
    }

    //深度平均分配
    public static ComplexityModel modelAverage(int wid_t, int dep_t, boolean withStatement, BaseModelFactory
            baseModelF) {
        //先处理with子旬
        ComplexityModel withModel = new ComplexityModel();
        setWithComp(withModel, wid_t, dep_t, withStatement, baseModelF);
        int rest_widt = wid_t - withModel.comps[DmSelect.INDEX_WITH].wid_t;
        int rest_dept = dep_t - withModel.comps[DmSelect.INDEX_WITH].dep_t;
        if (rest_dept == 0) {
            rest_dept = 1;
        }
        rest_dept = Randomly.getInteger(rest_dept, dep_t);

        //只考虑selelements,from,where子句。
        ComplexityModel model = BaseModelFactory.defaultModel(rest_widt, rest_dept, 3);
        boolean[] flags = BaseModelFactory.getRandExpTypes();
        if (!flags[BaseModelFactory.INDEX_SUBSELECT]) {//如果禁止子查询,那么查询列,where子句深度设置1,from子句深度设为要求深度
            //宽度就不做调整了
            model.comps[0].dep_t = 1;
            model.comps[1].dep_t = rest_dept;
            model.comps[2].dep_t = 1;
        }
        ComplexityModel model1 = new ComplexityModel();
        model1.setTargetComp(rest_widt, rest_dept);
        model1.comps[DmSelect.INDEX_ELEMENT].wid_t = model.comps[0].wid_t;
        model1.comps[DmSelect.INDEX_ELEMENT].dep_t = model.comps[0].dep_t;
        model1.comps[DmSelect.INDEX_FROM].wid_t = model.comps[1].wid_t;
        model1.comps[DmSelect.INDEX_FROM].dep_t = model.comps[1].dep_t;
        model1.comps[DmSelect.INDEX_WHERE].wid_t = model.comps[2].wid_t;
        model1.comps[DmSelect.INDEX_WHERE].dep_t = model.comps[2].dep_t;
        model1.comps[DmSelect.INDEX_WITH].wid_t = withModel.comps[DmSelect.INDEX_WITH].wid_t;
        model1.comps[DmSelect.INDEX_WITH].dep_t = withModel.comps[DmSelect.INDEX_WITH].dep_t;

        if (model1.comps[DmSelect.INDEX_ELEMENT].wid_t < 1) {
            throw new IllegalArgumentException();
        }
        //深度为1时,from子旬仅能使用表名,
        if (model1.comps[DmSelect.INDEX_FROM].dep_t == 1 && model1.comps[DmSelect.INDEX_FROM].wid_t != 1) {
            model1.comps[DmSelect.INDEX_FROM].wid_t = 1;
            model1.comps[DmSelect.INDEX_WHERE].wid_t = wid_t - 1 - model.comps[0].wid_t;
        }

        if (model1.comps[DmSelect.INDEX_WHERE].wid_t == 1) {
            model1.comps[DmSelect.INDEX_WHERE].wid_t = setWidtByDept(model1.comps[DmSelect.INDEX_WHERE].dep_t);
        }
        model1.weight = FactoryConstant.WEIGHT_AVERAGE;

        if (model1.comps[DmSelect.INDEX_ELEMENT].wid_t < 1) {
            throw new IllegalArgumentException();
        }
        //group子句
        setGroupModel(model1, wid_t, baseModelF);

        //having子旬
        setHavingModel(model1, dep_t, baseModelF);

        //order子句
        setOrderModel(model1, dep_t, baseModelF);

        setLimitModel(model1, baseModelF);
        setTopModel(model1, baseModelF);
//        setSampleModel(model1, baseModelF);

        return model1;
    }

    //极值分配,查询列
    private static ComplexityModel extremeSelElements(int wid_t, int dep_t,
                                                      boolean withStatement, BaseModelFactory baseModelF) {
        ComplexityModel modelSelElements = new ComplexityModel();
        setWithComp(modelSelElements, wid_t, dep_t, withStatement, baseModelF);
        int rest_widt = wid_t - modelSelElements.comps[DmSelect.INDEX_WITH].wid_t;
        int rest_dept = dep_t - modelSelElements.comps[DmSelect.INDEX_WITH].dep_t;
        if (rest_dept == 0) {
            rest_dept = 1;
        }
        rest_dept = Randomly.getInteger(rest_dept, dep_t);
        modelSelElements.setTargetComp(rest_widt, rest_dept);
        int g_width = setGroupModel(modelSelElements, rest_widt, baseModelF);
        int h_width = setHavingModel(modelSelElements, rest_dept, baseModelF);
        //modelSelElements.comps[DmSelect.INDEX_ELEMENT.wid_t = rest_widt - g_width - h_width;
        int o_width = setOrderModel(modelSelElements, rest_widt, baseModelF);
        modelSelElements.comps[DmSelect.INDEX_ELEMENT].wid_t = rest_widt - g_width - h_width - o_width;
        int l_width = setLimitModel(modelSelElements, baseModelF);
        modelSelElements.comps[DmSelect.INDEX_ELEMENT].wid_t = wid_t - g_width - h_width - l_width - o_width;
        int t_width = setTopModel(modelSelElements, baseModelF);
        modelSelElements.comps[DmSelect.INDEX_ELEMENT].wid_t = wid_t - g_width - h_width - l_width - o_width - t_width;
        int s_width = setTopModel(modelSelElements, baseModelF);
        modelSelElements.comps[DmSelect.INDEX_ELEMENT].wid_t = wid_t - g_width - h_width - l_width - o_width - t_width - s_width;

        if (modelSelElements.comps[DmSelect.INDEX_ELEMENT].wid_t < 1) {
            modelSelElements.comps[DmSelect.INDEX_ELEMENT].wid_t = 1;
        }
        modelSelElements.comps[DmSelect.INDEX_ELEMENT].dep_t = rest_dept;
        modelSelElements.weight = FactoryConstant.WEIGHT_EXTREME;
        return modelSelElements;
    }

    //极值分配，from子句
    private static ComplexityModel extremeFrom(int wid_t, int dep_t, boolean withStatement, BaseModelFactory
            baseModelF) {
        ComplexityModel modelFrom = new ComplexityModel();
        //将+和宽度放入到modelFrom.comps[DmSelect.INDEX_WITH]中
        setWithComp(modelFrom, wid_t, dep_t, withStatement, baseModelF);
        int rest_widt =wid_t - modelFrom.comps[DmSelect.INDEX_WITH].wid_t;
        int rest_dept =dep_t - modelFrom.comps[DmSelect.INDEX_WITH].dep_t;
        if (rest_dept == 0) {
            rest_dept = 1;
        }
        rest_dept = Randomly.getInteger(rest_dept, dep_t);
        //将hint深度和宽度放入modelFrom中
        modelFrom.setTargetComp(rest_widt, rest_dept);
        int ele_widt = setWidtByDept(1);  //根据深度设置宽度
        int from_widt = 0;
        //将element的的深度和宽度放入modelFrom中
        modelFrom.comps[DmSelect.INDEX_ELEMENT].wid_t = ele_widt;
        modelFrom.comps[DmSelect.INDEX_ELEMENT].dep_t = 1;
        //将from的深度和宽度放入modelFrom中
        modelFrom.comps[DmSelect.INDEX_FROM].dep_t = rest_dept;
        if (rest_dept != 1) {//深度为1时，from子句仅能使用表名，宽度为1
            from_widt = setWidtByDept(rest_dept);
        } else {
            from_widt = 1;
        }
        modelFrom.comps[DmSelect.INDEX_FROM].wid_t = from_widt;
        if (rest_widt - ele_widt - from_widt > 0) {
            //将where的深度和宽度放入modelFrom中
            modelFrom.comps[DmSelect.INDEX_WHERE].wid_t = rest_widt - ele_widt - from_widt;
            modelFrom.comps[DmSelect.INDEX_WHERE].dep_t = 1;
        }
        if (modelFrom.comps[DmSelect.INDEX_FROM].dep_t == 1 && modelFrom.comps[DmSelect.INDEX_FROM].wid_t != 1) {
            //深度为1时，from子句仅能使用表名
            throw new AssertionError();
        }
        //group子句
        //将group的深度和宽度放入modelFrom中
        setGroupModel(modelFrom, rest_widt, baseModelF);
        //having子句
        //将have的深度和宽度放入modelFrom中
        setHavingModel(modelFrom, rest_dept, baseModelF);
        //将order的深度和宽度放入modelFrom中
        setOrderModel(modelFrom, rest_dept, baseModelF);
        //为什么又调用了一次having方法
        setHavingModel(modelFrom, dep_t, baseModelF);
        //将limit的深度和宽度放入到modelFrom中
        setLimitModel(modelFrom, baseModelF);
        //将top的深度和宽度放入到modelFrom中
        setTopModel(modelFrom, baseModelF);
        //将simple的深度和宽度放入到modelFrom中
//        setSampleModel(modelFrom, baseModelF);
        //权重
        modelFrom.weight = FactoryConstant.WEIGHT_EXTREME;

        return modelFrom;
    }

    //极值分配，where子句
    private static ComplexityModel  extremeWhere(int wid_t, int dep_t, boolean withStatement, BaseModelFactory
            baseModelF) {
        ComplexityModel modelWhere = new ComplexityModel();
        setWithComp(modelWhere, wid_t, dep_t, withStatement, baseModelF);
        int used_widt = modelWhere.comps[DmSelect.INDEX_WITH].wid_t;
        int rest_widt = wid_t - used_widt;
        int rest_dept = dep_t - modelWhere.comps[DmSelect.INDEX_WITH].dep_t;
        if (rest_dept == 0) {
            rest_dept = 1;
        }
        rest_dept = Randomly.getInteger(rest_dept, dep_t);
        modelWhere.setTargetComp(rest_widt, rest_dept);
        modelWhere.comps[DmSelect.INDEX_WHERE].wid_t = setWidtByDept(rest_dept);
        modelWhere.comps[DmSelect.INDEX_WHERE].dep_t = rest_dept;
        used_widt += modelWhere.comps[DmSelect.INDEX_WHERE].wid_t;
        if (rest_dept == 1) {
            modelWhere.comps[DmSelect.INDEX_FROM].wid_t = 1;
            modelWhere.comps[DmSelect.INDEX_FROM].dep_t = 1;
            used_widt += 1;
            modelWhere.comps[DmSelect.INDEX_ELEMENT].wid_t = wid_t - used_widt;
            modelWhere.comps[DmSelect.INDEX_ELEMENT].dep_t = 1;
        } else {
            modelWhere.comps[DmSelect.INDEX_FROM].dep_t = Randomly.getInteger(1, rest_dept - 1);
            modelWhere.comps[DmSelect.INDEX_FROM].wid_t = setWidtByDept(modelWhere.comps[DmSelect.INDEX_FROM].dep_t);
            used_widt += modelWhere.comps[DmSelect.INDEX_FROM].wid_t;
            if (used_widt < wid_t) {
                modelWhere.comps[DmSelect.INDEX_ELEMENT].wid_t = wid_t - used_widt;
                modelWhere.comps[DmSelect.INDEX_ELEMENT].dep_t = 1;
            } else {
                modelWhere.comps[DmSelect.INDEX_FROM].wid_t = modelWhere.comps[DmSelect.INDEX_FROM].dep_t;
                used_widt = modelWhere.comps[DmSelect.INDEX_WHERE].wid_t
                        + modelWhere.comps[DmSelect.INDEX_FROM].wid_t
                        + modelWhere.comps[DmSelect.INDEX_WITH].wid_t;
                modelWhere.comps[DmSelect.INDEX_ELEMENT].wid_t = wid_t - used_widt;
                modelWhere.comps[DmSelect.INDEX_ELEMENT].dep_t = 1;
            }
        }
        if (modelWhere.comps[DmSelect.INDEX_ELEMENT].wid_t < 1) {
            modelWhere.comps[DmSelect.INDEX_ELEMENT].wid_t = 1;
        }
        //group子句
        setGroupModel(modelWhere, wid_t, baseModelF);
        //having子句
        setHavingModel(modelWhere, dep_t, baseModelF);
        //order子句
        setOrderModel(modelWhere, dep_t, baseModelF);

        setLimitModel(modelWhere, baseModelF);
        setTopModel(modelWhere, baseModelF);

        //权重
        modelWhere.weight = FactoryConstant.WEIGHT_EXTREME;

        return modelWhere;
    }

    //group子句分配
    //返回宽度
    private static int setGroupModel(ComplexityModel model, int width, BaseModelFactory baseModelF) {
        int g_width = 0;//表示不需要group子句
        if (baseModelF.testFlags[BaseModelFactory.FLAG_GROUP]
                && Randomly.getBoolean()) { //如果测试group子句，那么50%的几率有group子句
            //如果总宽度比SQLComplexity.WID LEVEL1小;那么仅设定1个分组项
            g_width = Randomly.getInteger(1, SQLComplexity.WID_LEVEL1 < width ? FactoryConstant.MAX_GROUPS : 1);
            //如果测试groupbycube子句，那么50%的几率有groupbycube子句
            //如果总宽度比SQLComplexity.WID:LEVEL1小那么仅设定1个分组项
            if (baseModelF.testFlags[BaseModelFactory.FLAG_GROUPBYCUBE]
                    && Randomly.getBoolean()) {
                g_width = Randomly.getInteger(1, SQLComplexity.WID_LEVEL1 < width ? FactoryConstant.MAX_GROUPBYCUBE : 1);
            }
        }
        if (g_width > 0) {
            model.comps[DmSelect.INDEX_GROUP].wid_t = g_width;
            model.comps[DmSelect.INDEX_GROUP].dep_t = 1;
        } else {
            model.comps[DmSelect.INDEX_GROUP].wid_t = 0;
            model.comps[DmSelect.INDEX_GROUP].dep_t = 0;
        }

        return g_width;
    }

    //having子句分配
    //返回宽度
    private static int setHavingModel(ComplexityModel model, int depth, BaseModelFactory baseModelF) {
        int h_width = 0; //表示不需要having子句
        if (baseModelF.testFlags[BaseModelFactory.FLAG_HAVING]
                && Randomly.getBoolean()) { //如果测试having子句，那么50%的几率有having于句
            h_width = Randomly.getInteger(3, FactoryConstant.MAX_HAVING_WIDTH);
        }
        if (h_width > 0) {
            model.comps[DmSelect.INDEX_HAVING].wid_t = h_width;
            if (depth > FactoryConstant.MAX_HAVING_DEPTH) {
                model.comps[DmSelect.INDEX_HAVING].dep_t = Randomly.getInteger(1, FactoryConstant.MAX_HAVING_DEPTH + 1);
            } else {
                model.comps[DmSelect.INDEX_HAVING].dep_t = Randomly.getInteger(1, depth);
            }
        }else {
            model.comps[DmSelect.INDEX_HAVING].wid_t = 0;
            model.comps[DmSelect.INDEX_HAVING].dep_t = 0;
        }
        return h_width;
    }

    //with子句分配，从总宽度，总深度中随机分配部分宽度和深度
    private static void setWithComp(ComplexityModel model, int wid_t,int dep_t,boolean withStatement, BaseModelFactory baseModelF) {
        if (withStatement) {//如果需要with子句
            if (wid_t < FactoryConstant.MIN_WIDT_COMP) {//如果总宽度过小，不设置with子句
                model.comps[DmSelect.INDEX_WITH].wid_t = 0;
                model.comps[DmSelect.INDEX_WITH].dep_t = 0;
                return ;
            }
            if (withStatement
                    && baseModelF.testFlags[BaseModelFactory.FLAG_WITH]
                    && Randomly.getBoolean()) {
                model.comps[DmSelect.INDEX_WITH].wid_t = Randomly.getInteger(wid_t > 2 * FactoryConstant.MIN_WIDT_COMP ? FactoryConstant.MIN_WIDT_COMP :10, wid_t);
                model.comps[DmSelect.INDEX_WITH].dep_t = Randomly.getInteger(1, dep_t);
            }
            return ;
        }
    }

    //order子句分配
    //返回宽度
    private static int setOrderModel(ComplexityModel model, int depth, BaseModelFactory baseModelF) {
        int o_width = 0;//表示不需要order子句
        if (baseModelF.testFlags[BaseModelFactory.FLAG_ORDER]
                && Randomly.getBoolean()) {//如果测试order子句，那么50%几率又order子句
            o_width = Randomly.getInteger(1, 10);
        }
        if (o_width > 0) {
            model.comps[DmSelect.INDEX_ORDER].wid_t = o_width;
            model.comps[DmSelect.INDEX_ORDER].dep_t = 1;
        } else {
            model.comps[DmSelect.INDEX_ORDER].wid_t = 0;
            model.comps[DmSelect.INDEX_ORDER].dep_t = 0;
        }
        return o_width;
    }

    //Top子句分配
    private static int setTopModel(ComplexityModel model, BaseModelFactory baseModelF) {
        int t_width = 0;//表示不需要top子句

        if (baseModelF.testFlags[BaseModelFactory.FLAG_TOP]
                && Randomly.getBoolean()) {
            t_width = 1;
        }
        if (t_width > 0) {
            model.comps[DmSelect.INDEX_TOP].wid_t = t_width;
            model.comps[DmSelect.INDEX_TOP].dep_t = 1;
        } else {
            model.comps[DmSelect.INDEX_TOP].wid_t = 0;
            model.comps[DmSelect.INDEX_TOP].dep_t = 0;
        }
        return t_width;
    }

    private static int setLimitModel(ComplexityModel model, BaseModelFactory baseModelF) {
        if (Randomly.getBoolean()) {
            return setLimOffsetModel(model, baseModelF);
        } else {
            return setRowLimitModel(model, baseModelF);
        }
    }

    //limit子句分配
    //返回宽度
    private static int setLimOffsetModel(ComplexityModel model, BaseModelFactory baseModelF) {
        int l_width = 0;//表示不需要limit子句

        if (baseModelF.testFlags[BaseModelFactory.FLAG_LIMIT]
                && Randomly.getBoolean()) {
            l_width = Randomly.getInteger(1, 3);//1,2
        }
        if (l_width > 0) {
            model.comps[DmSelect.INDEX_LIMIT].wid_t = l_width;
            model.comps[DmSelect.INDEX_LIMIT].dep_t = 1;
        } else {
            model.comps[DmSelect.INDEX_LIMIT].wid_t = 0;
            model.comps[DmSelect.INDEX_LIMIT].dep_t = 0;
        }
        return l_width;
    }

    //Rowlimit子句分配
    private static int setRowLimitModel(ComplexityModel model, BaseModelFactory baseModelF) {
        int rl_width = 0;//表示不需要RowLimit子句

        if (baseModelF.testFlags[BaseModelFactory.FLAG_LIMIT]
                && Randomly.getBoolean()) {
            rl_width = 2;
        }
        if (rl_width > 0) {
            model.comps[DmSelect.INDEX_ROWLIMIT].wid_t = rl_width;
            model.comps[DmSelect.INDEX_ROWLIMIT].dep_t = 1;
        } else {
            model.comps[DmSelect.INDEX_ROWLIMIT].wid_t = 0;
            model.comps[DmSelect.INDEX_ROWLIMIT].dep_t = 0;
        }
        return rl_width;
    }
}
